package com.by.rpc.util;

import com.by.log.Logger;
import com.by.log.LoggerFactory;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.HashMap;
import java.util.Map;

/**
 * 参数转换工具类
 * 用于将网关传递的requestData转换为具体方法需要的参数
 */
public class ParameterConverter {
    private static final Logger logger = LoggerFactory.getLogger(ParameterConverter.class);

    /**
     * 将requestData转换为方法需要的参数数组
     *
     * @param method     目标方法
     * @param requestData 网关传递的请求数据
     * @return 方法参数数组
     */
    public static Object[] convertParameters(Method method, Map<String, Object> requestData) {
        Parameter[] parameters = method.getParameters();
        Object[] args = new Object[parameters.length];

        // 从requestData中提取各种数据
        String path = (String) requestData.get("path");
        String methodType = (String) requestData.get("method");
        String queryString = (String) requestData.get("queryString");
        String body = (String) requestData.get("body");
        Map<String, String> headers = (Map<String, String>) requestData.get("headers");

        // 解析查询参数
        Map<String, String> queryParams = parseQueryString(queryString);

        for (int i = 0; i < parameters.length; i++) {
            Parameter param = parameters[i];
            Class<?> paramType = param.getType();

            // 如果参数是Map类型，直接传递requestData
            if (Map.class.isAssignableFrom(paramType)) {
                args[i] = requestData;
            }
            // 如果参数是基本类型或String，尝试从路径变量、查询参数或请求体中获取
            else if (isSimpleType(paramType)) {
                args[i] = extractSimpleParameter(param, path, queryParams, body, headers);
            }
            // 对于复杂对象，可以从请求体中反序列化
            else {
                args[i] = extractComplexParameter(paramType, body);
            }
        }

        return args;
    }

    /**
     * 判断是否为简单类型
     */
    private static boolean isSimpleType(Class<?> type) {
        return type.isPrimitive() ||
                type == String.class ||
                type == Integer.class || type == int.class ||
                type == Long.class || type == long.class ||
                type == Double.class || type == double.class ||
                type == Float.class || type == float.class ||
                type == Boolean.class || type == boolean.class ||
                type == Byte.class || type == byte.class ||
                type == Short.class || type == short.class ||
                type == Character.class || type == char.class;
    }

    /**
     * 提取简单参数
     */
    private static Object extractSimpleParameter(Parameter parameter, String path, 
                                               Map<String, String> queryParams, String body, 
                                               Map<String, String> headers) {
        // 获取参数名称（可能需要通过注解获取）
        String paramName = parameter.getName();
        
        // 尝试从查询参数中获取
        if (queryParams.containsKey(paramName)) {
            return convertStringValue(queryParams.get(paramName), parameter.getType());
        }
        
        // 尝试从路径中提取参数（需要根据具体路径匹配规则实现）
        // 这里简化处理，实际应该根据@PathVariable注解和路径模板匹配
        return null;
    }

    /**
     * 提取复杂参数（如DTO对象）
     */
    private static Object extractComplexParameter(Class<?> paramType, String body) {
        // 这里应该实现JSON反序列化逻辑
        // 由于是示例，暂时返回null
        logger.warn("Complex parameter type {} not supported yet", paramType.getName());
        return null;
    }

    /**
     * 解析查询字符串
     */
    private static Map<String, String> parseQueryString(String queryString) {
        Map<String, String> params = new HashMap<>();
        if (queryString != null && !queryString.isEmpty()) {
            String[] pairs = queryString.split("&");
            for (String pair : pairs) {
                String[] keyValue = pair.split("=");
                if (keyValue.length == 2) {
                    params.put(keyValue[0], keyValue[1]);
                }
            }
        }
        return params;
    }

    /**
     * 将字符串值转换为指定类型
     */
    private static Object convertStringValue(String value, Class<?> targetType) {
        if (value == null) {
            return null;
        }

        try {
            if (targetType == String.class) {
                return value;
            } else if (targetType == Integer.class || targetType == int.class) {
                return Integer.parseInt(value);
            } else if (targetType == Long.class || targetType == long.class) {
                return Long.parseLong(value);
            } else if (targetType == Double.class || targetType == double.class) {
                return Double.parseDouble(value);
            } else if (targetType == Float.class || targetType == float.class) {
                return Float.parseFloat(value);
            } else if (targetType == Boolean.class || targetType == boolean.class) {
                return Boolean.parseBoolean(value);
            } else if (targetType == Byte.class || targetType == byte.class) {
                return Byte.parseByte(value);
            } else if (targetType == Short.class || targetType == short.class) {
                return Short.parseShort(value);
            } else if (targetType == Character.class || targetType == char.class) {
                return value.charAt(0);
            }
        } catch (NumberFormatException e) {
            logger.warn("Failed to convert string value '{}' to type {}", value, targetType.getName());
        }

        return null;
    }
}